import datetime
import random
import numpy as np

class Evaluate:

    def __init__(self):
        pass

    def evaluate_travel_time(self, predicted, actual):
        ret = 0.0
        total = 0
        for intersection_id in actual.keys():
            for tollgate_id in actual[intersection_id].keys():
                for start_time_window in actual[intersection_id][tollgate_id].keys():
                    total += 1
                    drt = actual[intersection_id][tollgate_id][start_time_window]
                    prt = predicted[intersection_id][tollgate_id][start_time_window]
                    ret += abs((drt - prt) / drt)
        ret /= total
        return ret

    def evaluate_traffic_volume(self, predicted, actual):
        ret = 0.0
        total = 0
        for tollgate_id in actual.keys():
            for direction in actual[tollgate_id].keys():
                for start_time_window in actual[tollgate_id][direction].keys():
                    total += 1
                    fct = actual[tollgate_id][direction][start_time_window]
                    pct = predicted[tollgate_id][direction][start_time_window]
                    ret += abs((fct - pct) / fct)
        ret /= total
        return ret

    def evaluate_test(self, predicted, actual):
        '''
            predicted, actual should be numpy.ndarray
        '''
        ret = 0.0
        total = 0
        assert len(actual) == len(predicted)
        assert len(actual[0]) == len(predicted[0])
        assert len(actual[0][0]) == len(predicted[0][0])
        for i in range(len(actual)):
            for j in range(len(actual[i])):
                for k in range(len(actual[i,j])):
                    total += 1
                    fct = actual[i,j,k]
                    pct = predicted[i,j,k]
                    ret += abs((fct - pct) / fct)
        ret /= total
        return ret


def test_evaluate_travel_time():
    evaluate = Evaluate()
    predicted = {"A": {"2": {}, "3": {}}, "B": {"1": {}, "3": {}}, "C": {"1": {}, "3": {}}}
    actual = {"A": {"2": {}, "3": {}}, "B": {"1": {}, "3": {}}, "C": {"1": {}, "3": {}}}
    start_time_window_1 = datetime.datetime(2016, 7, 19, 0, 0, 0, 0)
    start_time_window_2 = datetime.datetime(2016, 7, 19, 0, 20, 0, 0)
    for intersection_id in actual.keys():
        for tollgate_id in actual[intersection_id].keys():
            actual[intersection_id][tollgate_id][start_time_window_1] = random.uniform(1, 100)
            actual[intersection_id][tollgate_id][start_time_window_2] = random.uniform(1, 100)
            predicted[intersection_id][tollgate_id][start_time_window_1] = random.uniform(1, 100)
            predicted[intersection_id][tollgate_id][start_time_window_2] = random.uniform(1, 100)
    print "MAPE = " + str(evaluate.evaluate_travel_time(predicted, actual))

def test_evaluate_traffic_volume():
    evaluate = Evaluate()
    predicted = {"1": {"0": {}, "1": {}}, "2": {"0": {}}, "3": {"0": {}, "1": {}}}
    actual = {"1": {"0": {}, "1": {}}, "2": {"0": {}}, "3": {"0": {}, "1": {}}}
    start_time_window_1 = datetime.datetime(2016, 7, 19, 0, 0, 0, 0)
    start_time_window_2 = datetime.datetime(2016, 7, 19, 0, 20, 0, 0)
    for tollgate_id in actual.keys():
        for direction in actual[tollgate_id].keys():
            actual[tollgate_id][direction][start_time_window_1] = int(random.uniform(1, 100))
            actual[tollgate_id][direction][start_time_window_2] = int(random.uniform(1, 100))
            predicted[tollgate_id][direction][start_time_window_1] = int(random.uniform(1, 100))
            predicted[tollgate_id][direction][start_time_window_2] = int(random.uniform(1, 100))
    print "MAPE = " + str(evaluate.evaluate_traffic_volume(predicted, actual))
